#include "xtypes.h"
#include "xaux.h"
#include "xmath.h"

#include <math.h>
#include <time.h>
#include <stdlib.h>

float_t xMath_round(float_t n)
{
	float_t fn = xMath_floor(n);
	return (n-fn)<0.5f ? fn : fn+1.0f;
}

float_t xMath_floor(float_t n)
{
	//return floor(n);

	longlong_t tmp = (longlong_t)n;
	n = (float_t)tmp;

	return n;
}

float_t xMath_ceil(float_t n)
{
	//return ceil(n);

	longlong_t tmp = (longlong_t)n;
	n = (float_t)tmp;
	
	if( tmp-n>FLT_EPSILON )
	{
		n += 1.0f;
	}

	return n;
}


long_t xMathPositiveMod(long_t v, long_t m)
{
// 	v = v%m;
// 	v = v<0 ? v+m:v;
// 	return v;
	return m!=0 ? (v%m+m)%m : 0;
}


float_t xMathRealMod(float_t v, float_t m)
{
	float_t delta = xMath_floor(v/m);
	v -= m*delta;
	return v;	
}

float_t xMath_rsqrt( float_t n )
{
    long_t i;
    float_t x2, y;

	x2 = n * 0.5f;
    y  = n;
    i  = * ( long_t * ) &y;
    i  = 0x5f3759df - ( i >> 1 );
    y  = * ( float_t * ) &i;
    y  = y * ( 1.5f - ( x2 * y * y ) );   // 1st iteration
    //y  = y * ( 1.5f - ( x2 * y * y ) );   // 2nd iteration, this can be removed

	return y;
}

float_t xMath_pow( float_t base, float_t power )
{
	return powf(base, power);
}

float_t xMath_sqrt( float_t n )
{
	return 1.0f / xMath_rsqrt(n);
}

float_t xMathFast_sqrt( float_t n )
{
	__asm
	{
		mov eax, n;
		sub eax, 0x3f800000;
		sar eax, 1;
		add eax, 0x3f800000;
	}
}

float_t xMath_fabs( float f )
{
	int_t tmp = * ( int_t * ) &f;
	tmp &= 0x7FFFFFFF;
	return * ( float_t * ) &tmp;
}


